<?php

// @formatter:off
/**
 * @file WCFlowManager.php
 * @author Alejandro Dario Simi
 * @date $Date: 2014-06-03 03:40:32 +0000 (Tue, 03 Jun 2014) $
 *
 * $Id: WCFlowManager.php 112 2014-06-03 03:40:32Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/trunk/includes/flow/WCFlowManager.php $
 */
// @formatter:on

class WCFlowManager extends WCSingleton {
	//
	// Constants.
	const TypeCollectionFlow = "CL";
	const TypeDirectoryFlow = "DI";
	const TypeTagFlow = "TA";
	//
	// Public class properties.
	//
	// Protected class properties.
	//
	// Protected properties.	
	/**
	 * @var WCConnection Database pointer shortcut.
	 */
	protected $_db;
	/**
	 * @var string Database tables' prefix shortcut.
	 */
	protected $_dbprefix;
	protected $_flows = array();
	//
	// Public methods.
	/**
	 * @todo doc
	 * @return WCFlow @todo doc
	 */
	public function currentFlow() {
		$out = false;

		if(isset($_REQUEST["flow"])) {
			$urlParam = explode(":", $_REQUEST["flow"]);

			if(in_array($urlParam[0], array(self::TypeCollectionFlow, self::TypeDirectoryFlow, self::TypeTagFlow))) {
				$item = self::GetFlowingItem($urlParam[0], $urlParam[1]);
				$out = $this->flowOf($item);
			}
		}

		return $out;
	}
	/**
	 * @todo doc
	 * @return string @todo doc
	 */
	public function currentUrlFlow() {
		$out = "";

		if(isset($_REQUEST["flow"])) {
			$out = "flow={$_REQUEST["flow"]}";
		}

		return $out;
	}
	/**
	 * @todo doc
	 * 
	 * @param WCFlowContainer $item @todo doc
	 * @return WCFlow @todo doc
	 */
	public function flowOf(WCFlowContainer &$item) {
		$type = $item->flowType();
		$id = $item->id();
		$key = "{$type}:{$id}";

		if(!isset($this->_flows[$key])) {
			$this->_flows[$key] = new WCFlow($type, $id);
		}

		return $this->_flows[$key];
	}
	/**
	 * @todo doc
	 *
	 * @param WCFlowContainer $continer @todo doc
	 * @param WCFlowItem[] $items  @todo doc
	 * @return boolean @todo doc
	 */
	public function registerFlow(WCFlowContainer &$continer, &$items) {
		$out = false;

		if($continer && $continer->ok()) {
			//
			// @{
			$stmtC = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[clean]";
			if($this->_db->has($stmtId)) {
				$stmtC = $this->_db->get($stmtId);
			} else {
				$query = "delete from {$this->_dbprefix}flows\n";
				$query.= "where       flw_group = :group\n";
				$query.= " and        flw_type  = :type\n";
				$query.= " and        flw_id    = :id\n";

				$stmtC = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// @{
			$stmtR = null;
			$stmtId = __CLASS__."::".__FUNCTION__."[register]";
			if($this->_db->has($stmtId)) {
				$stmtR = $this->_db->get($stmtId);
			} else {
				$query = "insert\n";
				$query.= "        into {$this->_dbprefix}flows (\n";
				$query.= "                flw_group, flw_type, flw_id, flw_position, flw_item_type, flw_item_id)\n";
				$query.= "        values (:group, :type, :id, :position, :item_type, :item_id)\n";

				$stmtR = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			// Building database parameters.
			$paramsC = array(
				":group" => $continer->group()->id(),
				":type" => $continer->flowType(),
				":id" => $continer->id()
			);
			$paramsR = $paramsC;

			$stmtC->execute($paramsC);

			$position = array();
			foreach($items as $item) {
				if(!$item instanceof WCFlowItem) {
					WCErrors::I()->error(WC_HTTPERROR_INTERNAL_SERVER_ERROR, "Wrong object type. 'WCFlowItem' spected, '".get_class($item)."' received.");
				}

				$type = $item->flowItemType();
				$id = $item->id();
				if(isset($position[$type])) {
					$position[$type] ++;
				} else {
					$position[$type] = 0;
				}
				$paramsR[":position"] = $position[$type];
				$paramsR[":item_type"] = $type;
				$paramsR[":item_id"] = $id;

				$stmtR->execute($paramsR);
			}

			$out = true;
		}

		return $out;
	}
	/**
	 * @todo doc
	 * 
	 * @param WCFlowContainer $item @todo doc
	 * @return string @todo doc
	 */
	public function urlFlowFor(WCFlowContainer &$item) {
		return "flow={$item->flowType()}:{$item->id()}";
	}
	//
	// Protected methods.
	protected function init() {
		parent::init();
		//
		// Loading shortcuts.
		// @{
		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $this->_db->prefix();
		// @}
	}
	//
	// Public class methods.
	/**
	 * @todo doc
	 *
	 * @param type $type @todo doc
	 * @param type $id @todo doc
	 * @return WCFlowContainer @todo doc
	 */
	public static function GetFlowingItem($type, $id) {
		$out = false;

		switch($type) {
			case self::TypeTagFlow:
				$out = WCTagsHolder::I()->item($id);
				break;
			case self::TypeDirectoryFlow:
				$out = WCDirectoriesHolder::I()->item($id);
				break;
			case self::TypeCollectionFlow:
				$out = WCCollectionsHolder::I()->item($id);
				break;
		}

		return $out;
	}
	//
	// Protected class methods.
}
